import sys, os, math, random

class party: 
  def __init__(self, names, votess, seat=0):
    self.name = names
    self.votes = votess
    self.readyseats = seat
    if self.readyseats == None:
      self.readyseats = int(0)
    self.seats = self.readyseats
    if self.seats == None:
      self.seats = int(0)
  
  def getquota(self):
    return self.votes/(self.seats + 1)
    
  def bumpseats(self):
    self.seats += 1
    
  def reset(self): #Sets seats counter back to readyseats
    self.seats = self.readyseats
    
    

def dhondt(parties, topups):
  i = 0
  elected = []
  while i < topups:
    elect = sorted(parties, key=lambda party: party.getquota())
    elect.reverse()
    elected.append(elect[0])
    elect[0].bumpseats()
    i += 1
  return elected
  
def gallagher(diffs): #Used to describe proportionality of an election
  sqdiffs = []
  for i in diffs:
    sqdiffs.append(i*i)
  #print sqdiffs  
  totsq = sum(sqdiffs)
  #print totsq
  return math.sqrt(totsq/2)


class constituency:
  def __init__(self, name, parties, region = None):
    self.parties = sorted(parties, key=lambda party: party.votes)
    self.parties.reverse()
    self.name = name
    self.region = region
    self.totalvotes = int(0)
    for i in self.parties:
      self.totalvotes += i.votes
    
  def get_elected(self):
    return self.parties[0]
    
  def get_region(self):
    return self.region
    
  def set_region(self, region):
    self.region = region
    
  def set_results(self, parties):
    self.parties = sorted(parties, key=lambda party: party.votes)
    self.parties.reverse()
    self.totalvotes = int(0)
    for i in self.parties:
      self.totalvotes += i.votes
    
  def uniform_swing(self, swing, from_party, to_party):
    for i in self.parties:
      #print i.name
      if i.name == from_party:
        i.votes -= int(((float(swing)/2.00)/100.00)*float(self.totalvotes))
        #print i.votes
      if i.name == to_party:
        i.votes += int(((float(swing)/2.00)/100.00)*float(self.totalvotes))
        #print i.votes
    self.update_parties()
      
  def mod_votes(self, votes, party):
    for i in self.parties:
      if i.name == party:
        i.votes += votes
    self.update_parties()
    
  def update_parties(self): #Makes sure the parties list is in the correct order; highest votes to lowest votes.
    self.parties = sorted(self.parties, key=lambda party: party.votes)
    self.parties.reverse()
    
class region(constituency):
  def __init__(self, name, parties, constituencies, topups):
    self.parties = sorted(parties, key=lambda party: party.votes)
    self.parties.reverse()
    self.name = name
    self.constituencies = constituencies
    self.topups = topups
    self.totalvotes = int(0)
    for i in self.parties:
      self.totalvotes += i.votes
      
  def set_results(self, parties):
    self.parties = sorted(parties, key=lambda party: party.votes)
    self.parties.reverse()
    self.totalvotes = int(0)
    for i in self.parties:
      self.totalvotes += i.votes
      
  def get_elected(self,top=0):
    if top == 0:
      top = self.topups
    con_win_names = []
    for i in self.constituencies:
      x = i.get_elected().name
      con_win_names.append(x)
      for j in self.parties:
        if x == j.name:
          j.bumpseats()
    d = dhondt(self.parties, top)
    for k in self.parties:
      k.reset()
    return d
    
  def constituency_uniform_swing(self, swing, from_party, to_party, const = None):
    if const != None:
      for i in self.constituencies:
        if i.name == const:
          i.uniform_swing(swing, from_party, to_party)
    else:
      for i in self.constituencies:
        i.uniform_swing(swing, from_party, to_party)

#labour = party("Labour", 128818, 9)
#libdem = party("Liberal Democrats", 31403, 0)
#conser = party("Conservatives", 17432, 0)
#snp = party("SNP", 39702, 0)

#parties = [labour, libdem, conser, snp]
#print dhondt(parties, 7)
#if __name__ == "__main__":
#  labour = party("labour", 10000,0)
#  libdem = party("lib dem", 8000,0)
#  a = constituency("A",[libdem,labour])
#  #print a.get_elected().name
#  glab = party("labour",100000,0)
#  glib = party("lib dem",40000,0)
#  b = region("Glasgow",[glib,glab],[a],1)
#  for i in b.get_elected(6):
#    print i.name
#    print i.votes
#    
#  b.uniform_swing(20, "labour", "lib dem")
#  for i in b.get_elected(6):
#    print i.name
#    print i.votes
#  x = raw_input()